package it.uniroma2.dtk.drp;

import it.uniroma2.dtk.dt.DT;
import it.uniroma2.exp.tools.AvgVarCalculator;
import it.uniroma2.util.math.ArrayMath;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.Vector;


public class DistributedParserLearner {

	private static DT ts = null;
	
	private static String output = null;
	private static int grade = 12;

	private static Random random_extractor = null;
	
	public static void main(String [] argv) throws Exception {

////		String input = "D:\\COMBINED\\WSJ";
////		output = "C:\\USERS_DATA\\FABIO\\LAVORO\\PROGETTI\\SAG_SVN\\DTK_CDS\\temp";
//		ts = new FFTConvolutionTSG(0, grade, true, false);
////		ts.setLambda(0);
////
////		treatPennTreeDir(new File(input+"\\24"));		
//
//		String input = argv[0];
//		output = argv[1];
//
//		ts = new FFTConvolutionTSG(0, grade, true, false);
//		ts.setLambda(0);
////		String [] es = new String [] {"24","15","21","11","14","03","00","22","08","06","12","09","18","17"};
//		String [] es = new String [] {"01","05","10","19","20"};
//		Vector <String> ex_dirs = new Vector <String> ();
//		for (int i=0;i<es.length;i++) ex_dirs.add(es[i]); 
//		File penntreebank = new File(input);
//		for (File dir:penntreebank.listFiles()) {
//			if (ex_dirs.contains(dir.getName())) treatPennTreeDir(dir);
//		}
		
		
		
//		SparseBinaryMatrix<Float> train = new SparseBinaryMatrix<Float>(Float.class); 
//		train.openFile(output + "\\prova.sbm", "rw",true); 
//		treatPennTreeDir(input + "00",train);

		
		
//// 	Parameter Estimation		

//		String base = "C:\\USERS_DATA\\FABIO\\LAVORO\\PROGETTI\\SAG_SVN\\DTK_CDS\\temp\\";
//		String exp = "BagOfPOS";
//		String k1  = "100";
//		System.out.print( exp + " : train small : k = " + k1 + "  : ");
//		evaluate(base  + exp +"\\24_0s_" + k1 + ".svm",base + "24_Z.svm",base +  exp +"\\24_0s_" + k1 + ".results");
//		System.out.print( exp + " : train all   : k = " + k1 + "  : ");
//		evaluate(base + exp +"\\24_00to20_" + k1 + ".svm",base + "24_Z.svm",base + exp +"\\24_00to20_" + k1 + ".results");
//
//		System.out.print( exp + " : NO TRAIN    :   : ");
//		evaluate(base + exp +"\\24_X_Y.svm",base + "24_Z.svm",base + exp +"\\24_X_Y.results");
//
//		String [] ks = {"100","500", "1000", "1100", "1200", "1300", "1400"};
//
//		
//		exp = "POSuni-bigrams";
//
//		System.out.print( exp + " : NO TRAIN    :   : ");
//		evaluate(base + exp +"\\24_X_Y.svm",base + "24_Z.svm",base + exp +"\\24_X_Y.results");
//
//		for (String k:ks) {
//			System.out.print(exp + " : train small : k = " + k + "  : ");
//			evaluate(base +  exp +"\\24_0s_" + k + ".svm",base + "24_Z.svm",base + exp +"\\24_0s_" + k + ".results");
//		}
//
//		for (String k:ks) {
//			System.out.print(exp + " : train   all : k = " + k + "  : ");
//			evaluate(base + exp +"\\24_00to20_" + k + ".svm",base + "24_Z.svm",base + exp +"\\24_00to20_" + k + ".results");
//		}
//
//		String [] ks2 = {"100","500", "1000",  "1400","2000"
//				,"3000","4000"
//				};
//
//		
//		exp = "POSuni-bi-tri-grams";
//
//		System.out.print( exp + " : NO TRAIN    :   : ");
//		evaluate(base + exp +"\\24_X_Y.svm",base + "24_Z.svm",base + exp +"\\24_X_Y.results");
//
//		for (String k:ks2) {
//			System.out.print(exp + " : train small : k = " + k + "  : ");
//			evaluate(base +  exp +"\\24_0s_" + k + ".svm",base + "24_Z.svm",base + exp +"\\24_0s_" + k + ".results");
//		}
//
//		for (String k:ks2) {
//			System.out.print(exp + " : train   all : k = " + k + "  : ");
//			evaluate(base + exp +"\\24_00to20_" + k + ".svm",base + "24_Z.svm",base + exp +"\\24_00to20_" + k + ".results");
//		}
//
		
		
//		String base = "C:\\USERS_DATA\\FABIO\\LAVORO\\PROGETTI\\SAG_SVN\\DTK_CDS\\temp\\";
//		double [][] oracle = load_oracle(base + "24_Z.svm");
//		
//		String exp = "BagOfPOS";
//		String k1  = "100";
//		
//		System.out.print( exp + " : train small : k = " + k1 + "  : ");
//		evaluate(oracle,base  + exp +"\\24_0s_" + k1 + ".svm");
//		System.out.print( exp + " : train all   : k = " + k1 + "  : ");
//		evaluate(oracle,base  + exp +"\\24_00to20_" + k1 + ".svm");
//
//		System.out.print( exp + " : NO TRAIN    :   : ");
//		evaluate(oracle,base  + exp +"\\24_X_Y.svm");
//
//		String [] ks = {"100","500", "1000", "1100", "1200", "1300", "1400"};
//
//		
//		exp = "POSuni-bigrams";
//
//
//		System.out.print( exp + " : NO TRAIN    :   : ");
//		evaluate(oracle,base  + exp +"\\24_X_Y.svm");
//
//
//		for (String k:ks) {
//			System.out.print(exp + " : train small : k = " + k + "  : ");
//			evaluate(oracle,base  + exp +"\\24_0s_" + k1 + ".svm");
//		}
//
//		
//		for (String k:ks) {
//			System.out.print(exp + " : train   all : k = " + k + "  : ");
//			evaluate(oracle,base  + exp +"\\24_00to20_" + k1 + ".svm");
//		}
//		
//
//		String [] ks1 = {"100","500", "1000", "1400", "2000"};
//
//		
//		exp = "POSuni-bi-tri-grams";
//
//		System.out.print( exp + " : NO TRAIN    :   : ");
//		evaluate(oracle,base  + exp +"\\24_X_Y.svm");
//
//		for (String k:ks1) {
//			System.out.print(exp + " : train small : k = " + k + "  : ");
//			evaluate(oracle,base  + exp +"\\24_0s_" + k1 + ".svm");
//		}
//
//		for (String k:ks1) {
//			System.out.print(exp + " : train   all : k = " + k + "  : ");
//			evaluate(oracle,base  + exp +"\\24_00to20_" + k1 + ".svm");
//		}

//		String base = "C:\\USERS_DATA\\FABIO\\LAVORO\\PROGETTI\\SAG_SVN\\DTK_CDS\\temp\\";
//		double [][] oracle = load_oracle(base + "24_Z.svm");
//		double [][] system = load_oracle(base + "POSuni-bi-tri-grams" + "\\24_0s_3000.svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
		
		
//		System.out.print("train small : k = 100  : ");
//		evaluate(base + "BagOfPOS\\24_0s_100.svm",base + "24_Z.svm",base + "BagOfPOS\\24_0s_100.results");
////		System.out.print("train small : k = 500 : ");
////		evaluate(base + "BagOfPOS\\24_0s_500.svm",base + "24_Z.svm",base + "BagOfPOS\\24_0s_500.results");
////		System.out.print("train small : k = 1000 : ");
////		evaluate(base + "BagOfPOS\\24_0s_1000.svm",base + "24_Z.svm",base + "BagOfPOS\\24_0s_1000.results");
////		System.out.print("train small : k = 2000 : ");
////		evaluate(base + "BagOfPOS\\24_0s_2000.svm",base + "24_Z.svm",base + "BagOfPOS\\24_0s_2000.results");
//
//		
//		System.out.print("train   all : k = 100  : ");
//		evaluate(base + "BagOfPOS\\24_00to20_100.svm",base + "24_Z.svm",base + "BagOfPOS\\24_00to20_100.results");
//		
////		System.out.print("no train    :vecchio   : ");
////		evaluate(base + "24_X_Y.svm",base + "24_Z.svm",base + "24_X_Y_new.results");
//		System.out.print("no train    :nuovo     : ");
//		evaluate(base + "BagOfPOS\\24_X_Y.svm",base + "24_Z.svm",base + "24_X_Y_new.results");
//		
////		double [] [] oracle = load_oracle(base + "24_Z.svm");
////		evaluate(oracle , base + "24_Z_1000_new.svm" , base + "24_1000_similarities.results");
		

		
//// 	Final EVALUATION
		
		
		String base = "C:\\USERS_DATA\\FABIO\\LAVORO\\PROGETTI\\SAG_SVN\\DTK_CDS\\temp\\";
		String exp = null;
		int k = 0;
		double [][] oracle = null, system = null;

		oracle = load_oracle(base + "23_Z.svm");
	
		exp = "BagOfPOS";

		
		System.out.print(exp + " : BASE : ");
		evaluate(base + exp +"\\23_X_Y.svm",base + "23_Z.svm",base + exp +"\\23_00to20_BASE.results");

		System.out.print(exp + " : POSITION : BASE : ");
		evaluate(oracle,base  + exp +"\\23_X_Y.svm");
		system = load_oracle(base + exp + "\\23_X_Y.svm");
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
		System.out.println( exp + " : Base : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations.txt"),oracle,system, 100, 0, 100).getFormattedResult(10));
		
		k = 100;
		System.out.print(exp + " : k = " + k + "  : ");
		evaluate(base + exp +"\\23_00to20_" + k + ".svm",base + "23_Z.svm",base + exp +"\\23_00to20_" + k + ".results");

		
		System.out.print(exp + " : POSITION : k = " + k + "  : ");
		evaluate(oracle,base  + exp +"\\23_00to20_" + k + ".svm");

		system = load_oracle(base + exp + "\\23_00to20_" + k + ".svm");
		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
	
		System.out.println( exp + " : DRP  : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations"+k+".txt"),oracle,system, 100, 0, 100).getFormattedResult(10));
		
		exp = "POSuni-bigrams";

		System.out.print(exp + " : BASE : ");
		evaluate(base + exp +"\\23_X_Y.svm",base + "23_Z.svm",base + exp +"\\23_00to20_BASE.results");

		System.out.print(exp + " : POSITION : BASE : ");
		evaluate(oracle,base  + exp +"\\23_X_Y.svm");

		system = load_oracle(base + exp + "\\23_X_Y.svm");

		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
	
		System.out.println( exp + " : Base : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations.txt"),oracle,system, 100, 0, 100).getFormattedResult(10));
		
		k = 1300;
		System.out.print(exp + " : k = " + k + "  : ");
		evaluate(base + exp +"\\23_00to20_" + k + ".svm",base + "23_Z.svm",base + exp +"\\23_00to20_" + k + ".results");

		System.out.print(exp + " : POSITION : k = " + k + "  : ");
		evaluate(oracle,base  + exp +"\\23_00to20_" + k + ".svm");

		system = load_oracle(base + exp + "\\23_00to20_" + k + ".svm");
		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
		
		System.out.println( exp + " : DRP : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations"+k+".txt"),oracle,system, 100, 0, 100).getFormattedResult(10));
		
		exp = "POSuni-bi-tri-grams";

		System.out.print(exp + " : BASE : ");
		evaluate(base + exp +"\\23_X_Y.svm",base + "23_Z.svm",base + exp +"\\23_00to20_BASE.results");

		System.out.print(exp + " : POSITION : BASE : ");
		evaluate(oracle,base  + exp +"\\23_X_Y.svm");

		system = load_oracle(base + exp + "\\23_X_Y.svm");
		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
	
		System.out.println( exp + " : Base : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations.txt"),oracle,system, 100, 0, 100).getFormattedResult(10));
		
		k = 3000;
		System.out.print(exp + " : k = " + k + "  : ");
		evaluate(base + exp +"\\23_00to20_" + k + ".svm",base + "23_Z.svm",base + exp +"\\23_00to20_" + k + ".results");

		System.out.print(exp + " : POSITION : k = " + k + "  : ");
		evaluate(oracle,base  + exp +"\\23_00to20_" + k + ".svm");

		
		system = load_oracle(base + exp + "\\23_00to20_" + k + ".svm");
		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));

		System.out.println( exp + " : DRP  : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations"+k+".txt"),oracle,system, 100, 0, 100).getFormattedResult(10));

		
///	//BIKEL
		exp = "Bikel\\23_input_from_trees_2";
		System.out.print(exp + " : BASE : ");
		evaluate(base + exp +"\\23_Z_CHK.svm",base + exp + "\\23_Z_PT.svm",base + exp +"\\23_00to20_BASE.results");

//		double [][] oracle = null, system = null;
		oracle = load_oracle(base + exp + "\\23_Z_PT.svm");

		System.out.print(exp + " : POSITION : BASE : ");
		evaluate(oracle,base + exp + "\\23_Z_PT.svm");

		system = load_oracle(base + exp + "\\23_Z_CHK.svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
		
		System.out.println( exp + " : DRP  : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations.txt"),oracle,system, 100, 0, 100).getFormattedResult(10));

		exp = "Bikel\\23_input_from_trees_no_lex_2";
		System.out.print(exp + " : BASE : ");
		evaluate(base + exp +"\\23_Z_CHK.svm",base + exp + "\\23_Z_PT.svm",base + exp +"\\23_00to20_BASE.results");

//		double [][] oracle = null, system = null;
		oracle = load_oracle(base + exp + "\\23_Z_PT.svm");

		System.out.print(exp + " : POSITION : BASE : ");
		evaluate(oracle,base + exp + "\\23_Z_PT.svm");

		system = load_oracle(base + exp + "\\23_Z_CHK.svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
		
		System.out.println( exp + " : DRP  : Correlazione : " +  spearman_correlation_on_trials(new File(base + exp +"\\23_correlations.txt"),oracle,system, 100, 0, 100).getFormattedResult(10));
		
		//// "VS CHK" +

//		exp = "Bikel\\23_input_from_trees_no_lex";
//		oracle = load_oracle(base + exp + "\\23_Z_PT.svm");
//
//		Constituent [] oracle_t = loadPennTrees(new File("D:\\COMBINED\\WSJ\\23"));
//		
//		
//		System.out.println(" Correlazione: " + spearman_correlation_and_similarity(oracle_t,oracle, 10000, 0));
//
//		oracle = load_oracle(base + exp + "\\23_Z_CHK.svm");
//		System.out.println(" Correlazione: " + spearman_correlation_and_similarity(oracle_t,oracle, 10000, 0));
		
		
		
//		int k = 0;
//
//		oracle = load_oracle(base + "Charniak" + "\\23_Z_CHK.svm");
//	
//		exp = "BagOfPOS";
//
//		
//		System.out.print("VS CHK" +exp + " : BASE : ");
//		evaluate(base + exp +"\\23_X_Y.svm",base + "Charniak" + "\\23_Z_CHK.svm",base + exp +"\\23_00to20_BASE.results");
//
//		System.out.print("VS CHK" +exp + " : POSITION : BASE : ");
//		evaluate(oracle,base  + exp +"\\23_X_Y.svm");
//
//		system = load_oracle(base + exp + "\\23_X_Y.svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
//		
//		
//		
//		k = 100;
//		System.out.print("VS CHK" +exp + " : k = " + k + "  : ");
//		evaluate(base + exp +"\\23_00to20_" + k + ".svm",base + "Charniak" + "\\23_Z_CHK.svm",base + exp +"\\23_00to20_" + k + ".results");
//
//		
//		System.out.print("VS CHK" +exp + " : POSITION : k = " + k + "  : ");
//		evaluate(oracle,base  + exp +"\\23_00to20_" + k + ".svm");
//
//		system = load_oracle(base + exp + "\\23_00to20_" + k + ".svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
//	
//		
//		exp = "POSuni-bigrams";
//
//		System.out.print("VS CHK" +exp + " : BASE : ");
//		evaluate(base + exp +"\\23_X_Y.svm",base + "Charniak" + "\\23_Z_CHK.svm",base + exp +"\\23_00to20_BASE.results");
//
//		System.out.print("VS CHK" +exp + " : POSITION : BASE : ");
//		evaluate(oracle,base  + exp +"\\23_X_Y.svm");
//
//		system = load_oracle(base + exp + "\\23_X_Y.svm");
//
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
//	
//		
//		k = 1300;
//		System.out.print("VS CHK" +exp + " : k = " + k + "  : ");
//		evaluate(base + exp +"\\23_00to20_" + k + ".svm",base + "Charniak" + "\\23_Z_CHK.svm",base + exp +"\\23_00to20_" + k + ".results");
//
//		System.out.print("VS CHK" +exp + " : POSITION : k = " + k + "  : ");
//		evaluate(oracle,base  + exp +"\\23_00to20_" + k + ".svm");
//
//		system = load_oracle(base + exp + "\\23_00to20_" + k + ".svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
//		
//		
//		exp = "POSuni-bi-tri-grams";
//
//		System.out.print("VS CHK" +exp + " : BASE : ");
//		evaluate(base + exp +"\\23_X_Y.svm",base + "Charniak" + "\\23_Z_CHK.svm",base + exp +"\\23_00to20_BASE.results");
//
//		System.out.print("VS CHK" +exp + " : POSITION : BASE : ");
//		evaluate(oracle,base  + exp +"\\23_X_Y.svm");
//
//		system = load_oracle(base + exp + "\\23_X_Y.svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
//	
//		
//		k = 3000;
//		System.out.print("VS CHK" +exp + " : k = " + k + "  : ");
//		evaluate(base + exp +"\\23_00to20_" + k + ".svm",base + "Charniak" + "\\23_Z_CHK.svm",base + exp +"\\23_00to20_" + k + ".results");
//
//		System.out.print("VS CHK" +exp + " : POSITION : k = " + k + "  : ");
//		evaluate(oracle,base  + exp +"\\23_00to20_" + k + ".svm");
//
//		
//		system = load_oracle(base + exp + "\\23_00to20_" + k + ".svm");
//		
//		System.out.println(" Correlazione: " + spearman_correlation(oracle,system, 10000, 0));
		

		
		
		
	}
	
	
	
	
	private static void treatPennTreeDirDBM(File [] input_dirs, String output_file) throws Exception {
		
		DenseBinaryMatrix <Float> x_y = new DenseBinaryMatrix<Float> (Float.class);
		x_y.openFile(output_file + "_X_Y.dbm", "rw",true); 

		DenseBinaryMatrix <Float> z = new DenseBinaryMatrix<Float> (Float.class);
		z.openFile(output_file + "_X_Y.dbm", "rw",true); 
		
		
		int rows = 0;
		int columns = (int) Math.pow(2, grade);
		x_y.setCol(columns);
		z.setCol(columns);
		
		for (File dir:input_dirs) { 
			System.out.println("Dir: " + dir.getName());
			File [] files = dir.listFiles();

			if (files != null) {
				for (File f:files) {
					System.out.println("    File: " + f.getName());
					BufferedReader in = new BufferedReader(new FileReader(f));
					
					String parsed_sentence = loadPennTree(in);
					
					while (parsed_sentence != null) {
						System.out.print(".");
						XDG x = new XDG();
						x.fromPennTree(parsed_sentence);
						polishPennTree(x);
						//System.out.println("NEW : " + x.toPennTree());
						
//						double [] dtf = ts.cds(x);
						double [] dpos = dpos(x);
						
//						writeVector(x_y,dpos);
//						writeVector(z,dtf);
						parsed_sentence = loadPennTree(in);
						
					}
					System.out.println();
					in.close();
				}
				
				x_y.setSize(rows, columns); 
				x_y.writeSize();
				
				z.setSize(rows, columns);
				z.writeSize();
			}
			
		}
		
		
		
	}

	private static Constituent [] loadPennTrees(File input_pt) throws Exception {
		
		Vector <Constituent> trees = new Vector <Constituent> ();
		System.out.println("Dir: " + input_pt.getName());
		File [] files = input_pt.listFiles();
		
		if (files != null) {
			
			for (File f:files) {
				//String input_name =f.getName().split("\\.")[0];
				System.out.print(".");
				BufferedReader in_pt = new BufferedReader(new FileReader(f));
				String parsed_sentence_pt = DistributedParserLearner.loadPennTree(in_pt);
				while (parsed_sentence_pt != null) {
					XDG x = new XDG();
					x.fromPennTree(parsed_sentence_pt);
					DistributedParserLearner.polishPennTree(x);
					trees.add((Constituent) x.getSetOfConstituents().elementAt(0));
					parsed_sentence_pt = DistributedParserLearner.loadPennTree(in_pt);
				}
				in_pt.close();
			}
			System.out.println();
		}
		
		
		Constituent [] array_trees = new Constituent [trees.size()];
		return trees.toArray(array_trees);
		
		
	}


	private static void evaluate(double[][] oracle, String system) throws IOException, Exception {
		// TODO Auto-generated method stub
		random_extractor = new Random(0);
		BufferedReader s = new BufferedReader(new FileReader(system));
		
		AvgVarCalculator results = new AvgVarCalculator();
		String s_s = s.readLine();
		
		int [] dim = new int [2];
		dim[0] = new Integer(s_s.split(" ")[0]);
		dim[1] = new Integer(s_s.split(" ")[1]);
		int out = 0;
		for (int i=0; i < dim[0]; i++) {
			SortedSet<ComparableResult> res = new TreeSet<ComparableResult> (); 
			if (i%100==0) System.out.print(".");
			s_s = s.readLine();
			double [] sv = convertStringVector(s_s,dim[1]);
			res.add(new ComparableResult("YES",ArrayMath.cosine(sv,oracle[i])));
			
			for (int j = 0 ; j < 24 ; j++) { 
				int rand_num = random_extractor.nextInt(dim[0]);
				if (rand_num == i) j--;
				else res.add(new ComparableResult("NO",ArrayMath.cosine(sv,oracle[rand_num])));

			}
			Iterator <ComparableResult> iter = res.iterator();
			int position = 0;
			while (iter.hasNext()) {
				position ++;
				ComparableResult result = iter.next();
				if (result.good.equals("YES")) {
					out += position;
					results.addSample(position);
				}
			}

		}
		System.out.println( " Posizione media : " + results.getFormattedResult());
		s.close();
		
	}


	
	private static AvgVarCalculator spearman_correlation_on_trials(File out,double[][] oracle, double[][] system, int lenght_of_the_comparison, int random_seed, int trials) throws Exception  {
		Random r = new Random(random_seed);
		AvgVarCalculator results = new AvgVarCalculator();
		BufferedWriter out_stream = new BufferedWriter(new FileWriter(out));
		for (int i=0;i<trials;i++) {
			double d = spearman_correlation(oracle,system,lenght_of_the_comparison,r.nextInt(100000));
			out_stream.write("" + d + "\n");
			results.addSample(d);
		}
		out_stream.close();
		return results;
	}
	
	private static double spearman_correlation(double[][] oracle, double[][] system, int lenght_of_the_comparison, int random_seed) throws Exception {
		
		SpearmanCorrelation corr = new SpearmanCorrelation();

		Random r = new Random(random_seed);
		
		float [] oracle_a = new float[lenght_of_the_comparison], system_a = new float[lenght_of_the_comparison];
		
		for (int i = 0; i < lenght_of_the_comparison; i++) {
			int a = r.nextInt(oracle.length), b = r.nextInt(oracle.length);
			oracle_a[i] = (float) ArrayMath.cosine(oracle[a], oracle[b]);
			system_a[i] = (float) ArrayMath.cosine(system[a], system[b]);
//			oracle_a[i] = (float) ArrayMath.dot(oracle[a], oracle[b]);
//			system_a[i] = (float) ArrayMath.dot(system[a], system[b]);
		}
		
		return corr.spearmanCorrelationCoefficient(oracle_a, system_a) ;
		
	}
 

	private static double spearman_correlation_and_similarity(Constituent[] oracle_t, double[][] oracle_v, int lenght_of_the_comparison, int random_seed) throws Exception {
		
		SpearmanCorrelation corr = new SpearmanCorrelation();
		TreeKernel.lambda = 0;
		TreeKernel.lexicalized = false;
		Random r = new Random(random_seed);
		
		AvgVarCalculator res = new AvgVarCalculator();
		
		
		
		float [] oracle_t_a = new float[lenght_of_the_comparison], oracle_v_a = new float[lenght_of_the_comparison];
		
		for (int i = 0; i < lenght_of_the_comparison; i++) {
			int a = r.nextInt(oracle_t.length), b = r.nextInt(oracle_t.length);
//			oracle_t_a[i] = (float) ProductionKernel.value(oracle_t[a], oracle_t[b]);
//			oracle_v_a[i] = (float) ArrayMath.dot(oracle_v[a], oracle_v[b]);

			oracle_t_a[i] = (float) ProductionKernel.value(oracle_t[a], oracle_t[b])/(float)(Math.sqrt((float) ProductionKernel.value(oracle_t[a], oracle_t[a])*ProductionKernel.value(oracle_t[b], oracle_t[b])));
			oracle_v_a[i] = (float) ArrayMath.cosine(oracle_v[a], oracle_v[b]);
			
			res.addSample(oracle_t_a[i]/oracle_v_a[i]);
		}
		
		System.out.println(res.getFormattedResult(10));
		
		return corr.spearmanCorrelationCoefficient(oracle_t_a, oracle_v_a) ;
		
	}
 
	
	
	
	
	private static double[][] load_oracle(String oracle_file) throws IOException {
		BufferedReader o = new BufferedReader(new FileReader(oracle_file));
		String o_s = o.readLine();
		int [] dim = new int [2];
		dim[0] = new Integer(o_s.split(" ")[0]);
		dim[1] = new Integer(o_s.split(" ")[1]);

		double [] [] oracle = new double[dim[0]][dim[1]]; 
		
		for (int i=0; i < dim[0]; i++) {
			o_s = o.readLine();
			if (i%100==0) System.out.print(".");
			oracle[i] = convertStringVector(o_s,dim[1]);
		}
		System.out.println();
		o.close();
		return oracle;
	}




	private static void evaluate(String system, String oracle, String results) throws Exception {

		BufferedReader o = new BufferedReader(new FileReader(oracle));
		BufferedReader s = new BufferedReader(new FileReader(system));
		BufferedWriter r = new BufferedWriter(new FileWriter(results));
		
		String o_s = o.readLine();
		String s_s = s.readLine();
		
		AvgVarCalculator res_sim = new AvgVarCalculator(); 
		AvgVarCalculator res_f = new AvgVarCalculator(); 
		
		int [] dim = new int [2];
		dim[0] = new Integer(o_s.split(" ")[0]);
		dim[1] = new Integer(o_s.split(" ")[1]);


		double tot_fmeasure = 0;
		double tot_similarity = 0;
		for (int i=0; i < dim[0]; i++) {
			if (i%1000==0) System.out.print(".");
			o_s = o.readLine();
			s_s = s.readLine();
			double [] ov = convertStringVector(o_s,dim[1]);
			double [] sv = convertStringVector(s_s,dim[1]);
			
			double fmeasure = 2*ArrayMath.dot(ov, sv)/(ArrayMath.dot(ov,ov) + ArrayMath.dot(sv,sv));
			double similarity = ArrayMath.cosine(ov, sv);
//			r.write("" + fmeasure +"\n");
			r.write(("" + ArrayMath.dot(ov, sv) + "\t"  + ArrayMath.dot(ov,ov) + "\t"  + ArrayMath.dot(sv,sv)  + "\n").replace('.', ','));

//			double fmeasure = ArrayMath.cosine(ov, sv);
//			r.write("" + fmeasure +"\n");
			res_sim.addSample(Math.abs(similarity));
			res_f.addSample(Math.abs(fmeasure));
			tot_similarity += Math.abs(similarity);
			tot_fmeasure += Math.abs(fmeasure);
		}
		System.out.println("F-measure = " + res_f.getFormattedResult() + "\t Similarity " + res_sim.getFormattedResult());
		r.close();o.close();s.close();
	}




	private static void treatPennTreeDir(File dir) throws Exception {
		
		System.out.println("Dir: " + dir.getName());
		File [] files = dir.listFiles();

		if (files != null) {
			String base_file = output;
			BufferedWriter x_y = new BufferedWriter(new FileWriter(new File(base_file, dir.getName() + "_X_Y.svm")));
//			BufferedWriter z = new BufferedWriter(new FileWriter(new File(base_file, dir.getName() + "_Z.svm")));
			
			for (File f:files) {
				System.out.println("    File: " + f.getName());
				BufferedReader in = new BufferedReader(new FileReader(f));
				
				String parsed_sentence = loadPennTree(in);
				
				while (parsed_sentence != null) {
					System.out.print(".");
					XDG x = new XDG();
					x.fromPennTree(parsed_sentence);
					polishPennTree(x);
					//System.out.println("NEW : " + x.toPennTree());
					
//					double [] dtf = ts.cds(x);
					double [] dpos = dpos(x);
					
					writeVector(x_y,dpos);
//					writeVector(z,dtf);
					parsed_sentence = loadPennTree(in);
					
				}
				System.out.println();
				in.close();
			}
			
			x_y.close(); 
//			z.close();
		}
	}

	
	
	public static void writeVector(BufferedWriter out, double[] dpos) throws IOException {
		out.write("-1\t" + (1) + ":" + dpos[0]);
		for (int i=1; i<dpos.length; i++) {
			out.write( " " + (i+1) + ":" + dpos[i]);
		}
		out.write("\n");
	}

	private static double [] convertStringVector(String vector,int dim) {
		String [] vector_elements = vector.split("\t")[1].split(" ");
		double[] original_vector = new double[new Integer(dim)];
		for (int j=1; j < vector_elements.length; j++) {
			original_vector[new Integer(vector_elements[j].split(":")[0]) - 1] = 
				new Double(vector_elements[j].split(":")[1]);
		}
		return original_vector;
	}


	
	public static XDG polishPennTree(XDG x) {
		Constituent c = (Constituent) x.getSetOfConstituents().elementAt(0);
		polishPennTree(c);
		return x;
	}


	private static Constituent polishPennTree(Constituent c) {
		Constituent out = null;
		if (c instanceof SimpleConst) {
			
			//System.out.println(" +++ " + c.getType());
			if (!((SimpleConst) c).getSurface().trim().contains("*")) out = c; 
//			else {
//				System.out.println(" >>> " + c.getType());
//			}
		} else {
			Vector<Constituent> cc  = (Vector<Constituent>) ((ComplxConst) c).getSubConstituents();
			ConstituentList new_cc = new ConstituentList();
			for (Constituent o:cc) {
				Constituent new_o = polishPennTree(o);
				if (new_o!=null) new_cc.add(o);
			}
			if (new_cc.size() != 0) {
				((ComplxConst) c).setSubConstituents(new_cc);
				out = c;
			}
		}
		if (out != null) {
			if (c.getType().contains("-")) c.setType(c.getType().substring(0,c.getType().indexOf('-')) ); 
		}
		return out;
	}





	private static double [] dpos(XDG tree) throws Exception {
		Vector <Constituent> cc = (Vector <Constituent>) tree.getSetOfConstituents().getSimpleConstituentList();
		
		double [] out = null;
		
		for (int i = cc.size(); i > 0; i--) {
			if (out == null) out = ts.getTypeVector(cc.elementAt(i-1).getType());
//POS-SEQUENCE			else out = ts.op(ts.getTypeVector(cc.elementAt(i-1).getType()),out);
//BagOfPOS				else out = ArrayMath.sum(out, ts.getTypeVector(cc.elementAt(i-1).getType()));
			else {
				//BagOfPOS:unigrams+bigrams
				// UNIGRAMMA
				out = ArrayMath.sum(out, ts.getTypeVector(cc.elementAt(i-1).getType()));
				// BIGRAMMA
				double  [] bi = ts.op(ts.getTypeVector(cc.elementAt(i-1).getType()),ts.getTypeVector(cc.elementAt(i).getType()));		
				out = ArrayMath.sum( out , bi );
				// TRIGRAMMA
				if (i-2 >= 0) {
					double  [] tri = ts.op(ts.getTypeVector(cc.elementAt(i-2).getType()),bi);		
					out = ArrayMath.sum( out , tri );
				}
				
			}
		}
		
		return out;
	}
	
	
	public static  String loadPennTree(BufferedReader in) throws IOException{
		String input = in.readLine();
		String output = null;
		int open_pars = 0;
		while (input != null && input.trim().equals("")) input = in.readLine();
		if (input!=null)  {
			open_pars = count_chars(input,'(') - count_chars(input,')');
			output = input.trim();
		}
		while (input != null && open_pars > 0) {
			input = in.readLine();
			open_pars += count_chars(input,'(') - count_chars(input,')');
			output += " " + input.trim();
		}
		return output;
	}





	private static  int count_chars(String input, char c) {
		int count = 0;
		
		for (int i = 0;i < input.length(); i++) {
			count += (input.charAt(i)==c? 1 : 0);
		}
		
		return count;
	}
	
}



